home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / MacOS / QuickDraw™ 3D 1.0.6F4 SDK / Samples / SampleCode / Skinny3DSample / ValueControls ƒ / ValueControls.c next >
Encoding:
C/C++ Source or Header  |  1995-11-13  |  10.9 KB  |  489 lines  |  [TEXT/MPS ]

  1. #include "Printing.h"
  2. #include "Windows.h"
  3. #include "Fonts.h"
  4. #include "Desk.h"
  5. #include "ToolUtils.h"
  6. #include "TextUtils.h"
  7. #include "LowMem.h"
  8. #include "SegLoad.h"
  9. #include    <fp.h>
  10. #include     "ValueControls.h"
  11.  
  12. #define    kVCHeight    12
  13. #define kVCWidth    192
  14. #define kValuePos    142 // right edge (right flush)
  15. #define kDecHitPos    156
  16. #define kIncHitPos    172
  17. #define kResetWidth  36
  18.  
  19. enum { 
  20.     kSettingsDlog = 1280
  21. };
  22.  
  23. enum {
  24.     iVCtitle = 3,
  25.     iMinValue,
  26.     iMaxValue,
  27.     iStepSize,
  28.     iCurrentV
  29. };
  30.  
  31. // private structures
  32.  
  33. struct ValueCtlRec {
  34.     Str255        title;
  35.     float        initV;
  36.     float        currV;
  37.     float        mini;
  38.     float        maxi;
  39.     float        delta;
  40.     Point        titlePos;    // absolute window coordinates; initialized from ValueCtlCluster
  41.     Point        valuePos;
  42.     Rect        wholeRect;
  43.     Rect        incrHit;
  44.     Rect        decrHit;
  45.     long        lastClick;
  46.     Boolean        isCheckBox;
  47. };
  48. typedef struct ValueCtlRec ValueCtlRec, *VcPtr;
  49.  
  50. struct ValueCtlCluster {
  51.     OSType        idTag;
  52.     Str255        vTitle;
  53.     long        howMany;            // 1-based
  54.     Rect        frame;                // tries to position controls by itself; 
  55.                                     // may add scrollbars if required, later.
  56.     Rect        resetHit;
  57.     long        vcHeight;            // height of one ValueCtlRec in pixels
  58.     long        maxEntries;            // 1-based
  59.     VcPtr        vCtls[1];            // 0-based
  60. };
  61. typedef struct ValueCtlCluster ValueCtlCluster;
  62.  
  63. static VcPtr    NewValueCtl(Str255 title, float initV, float mini, float maxi, float delta);
  64. static void     DrawValueCtl(VcPtr v);
  65. static void        IncrementVC(VcPtr v);
  66. static void        DecrementVC(VcPtr v);
  67. static Boolean     DoSettingsDialog(VcPtr v);
  68.  
  69. // from TextUtils.h:
  70. extern pascal StringPtr C2PStr(Ptr cString);
  71. extern pascal Ptr P2CStr(StringPtr pString);
  72.  
  73. // from my dialog utilities:
  74. void    PutFloat(DialogPtr dlg, short item, float value);
  75. float    GetFloat(DialogPtr dlg, short item);
  76.  
  77. //----------------------------------------------------------------------
  78. VcPtr    NewValueCtl(Str255 title, float    initV, float mini, float maxi, float delta)
  79. {
  80.     VcPtr    v;
  81.     Rect        r;
  82.     
  83.     v = (VcPtr)NewPtr(sizeof(ValueCtlRec));
  84.     if (v != nil) {
  85.         BlockMove((Ptr)title, (Ptr)v->title, (long)title[0]+1);
  86.         v->initV = initV;
  87.         v->currV = initV;
  88.         v->mini  = mini;
  89.         v->maxi  = maxi;
  90.         v->delta = delta;
  91.         v->titlePos.h = 4;
  92.         v->titlePos.v = kVCHeight - 2;
  93.         v->valuePos.h = kValuePos;
  94.         v->valuePos.v = kVCHeight - 2;
  95.         SetRect(&v->wholeRect, 0, 0, kVCWidth, kVCHeight);
  96.         SetRect(&r, 0, 0, kVCHeight - 2, kVCHeight - 2);
  97.         OffsetRect(&r, kDecHitPos, 1);
  98.         v->decrHit    = r;
  99.         OffsetRect(&r, kIncHitPos - kDecHitPos, 0);
  100.         v->incrHit    = r;
  101.         v->lastClick = 0;
  102.         v->isCheckBox = ((mini == 0.0) && (maxi == 1.0) && (delta == 1.0));
  103.     }
  104.     return v;
  105. }
  106.  
  107. //----------------------------------------------------------------------
  108. VccPtr    NewVCluster(long tag, Str255 title, long numEntries, Rect *bounds)
  109. {
  110.     Rect    r = *bounds; // avoid side effects on bounds parameter!
  111.     long     size;
  112.     VccPtr     vcc;
  113.     
  114.     InsetRect(&r, 4, 4);
  115.     r.top += 4;
  116.     if ( (numEntries + 1) * kVCHeight > (r.bottom - r.top) )
  117.         return nil; // don't have enough space
  118.         
  119.     r.bottom = r.top + numEntries * kVCHeight + 10;
  120.     size = sizeof(ValueCtlCluster) + (numEntries - 1) * sizeof(VcPtr);
  121.     vcc = (VccPtr)NewPtr(size);
  122.     if (vcc != nil) {
  123.         vcc->idTag = tag;
  124.         BlockMove((Ptr)title, (Ptr)vcc->vTitle, (long)title[0] + 1);
  125.         vcc->howMany = 0;
  126.         vcc->frame = r;
  127.         vcc->vcHeight = kVCHeight;
  128.         vcc->maxEntries = numEntries;
  129.         SetRect(&r, 0, 0, kResetWidth, kVCHeight - 1);
  130.         OffsetRect(&r, vcc->frame.right - kResetWidth - 6, vcc->frame.top - 6);
  131.         vcc->resetHit = r;
  132.     }
  133.     return vcc;
  134. }
  135.  
  136.  
  137. //----------------------------------------------------------------------
  138. void AddValueCtl(VccPtr vcc, Str255 title, float initV, float mini, float maxi, float delta)
  139.  
  140. {
  141.     VcPtr    v;
  142.     Point    offset;
  143.     
  144.     if (vcc->howMany >= vcc->maxEntries)
  145.         return;
  146.     v = NewValueCtl(title, initV, mini, maxi, delta);
  147.     if (!v)
  148.         return;
  149.     offset.v = vcc->frame.top + (vcc->howMany + 1) * (vcc->vcHeight) - 6;
  150.     offset.h = vcc->frame.left + 2;
  151.     AddPt(offset, &v->titlePos);
  152.     AddPt(offset, &v->valuePos);
  153.     OffsetRect(&v->wholeRect, offset.h, offset.v);
  154.     SectRect(&vcc->frame, &v->wholeRect, &v->wholeRect);
  155.     v->wholeRect.right -= 2;
  156.     OffsetRect(&v->incrHit, offset.h, offset.v);
  157.     OffsetRect(&v->decrHit, offset.h, offset.v);
  158.     vcc->vCtls[vcc->howMany] = v;
  159.     vcc->howMany++;
  160. }
  161.  
  162. //----------------------------------------------------------------------
  163. void    AddSeparator(VccPtr vcc)
  164. {
  165.     AddValueCtl(vcc, "\p------------", 0.0,  0.0,  0.0, 0.0);
  166. }
  167.  
  168.  
  169. //----------------------------------------------------------------------
  170. Boolean    TakeHit(Point clickPt, VccPtr vcc)
  171. {
  172.     long         i, ticks;
  173.     Rect        r;
  174.     Boolean     isDblClick = false;
  175.     
  176.     i = 0;
  177.     r = vcc->resetHit;
  178.     if ( PtInRect(clickPt, &r) ) { // an afterthought ...
  179.         InvertRect(&r);
  180.          do {
  181.             vcc->vCtls[i]->currV = vcc->vCtls[i]->initV;
  182.             DrawValueCtl(vcc->vCtls[i]);
  183.         } while (++i < vcc->howMany);
  184.         InvertRect(&r);
  185.         return true;
  186.     }
  187.  
  188.     // i = 0;
  189.     
  190.     do {
  191.         if ((vcc->vCtls)[i]->mini < (vcc->vCtls)[i]->maxi) { 
  192.         // take hits only in real control lines
  193.             r = (vcc->vCtls)[i]->incrHit;
  194.             if ( PtInRect(clickPt, &r) ) {
  195.                 InvertRect(&r);
  196.                 IncrementVC((vcc->vCtls)[i]);
  197.                 goto newValue;
  198.             }
  199.             r = (vcc->vCtls)[i]->decrHit;
  200.             if ( PtInRect(clickPt, &r) ) {
  201.                 InvertRect(&r);
  202.                 DecrementVC((vcc->vCtls)[i]);
  203.                 goto newValue;
  204.             }
  205.             r = (vcc->vCtls)[i]->wholeRect;
  206.             if ( PtInRect(clickPt, &r) ) {
  207.                 ticks = ((vcc->vCtls)[i])->lastClick;
  208.                 isDblClick = (TickCount() - ticks < LMGetDoubleTime());
  209.                 ((vcc->vCtls)[i])->lastClick = TickCount();
  210.             }    
  211.             if ((isDblClick) && DoSettingsDialog((vcc->vCtls)[i])) {
  212.                 DrawValueCtl((vcc->vCtls)[i]);
  213.                 return true;
  214.             }
  215.             else
  216.                 isDblClick = false;
  217.         }
  218.     }  while ( (++i < vcc->howMany) );
  219.  
  220.     return false;
  221.     
  222. newValue:
  223.         Delay(6, &ticks);
  224.         InvertRect(&r);
  225.         ((vcc->vCtls)[i])->lastClick = TickCount();
  226.         DrawValueCtl((vcc->vCtls)[i]);
  227.         return true;
  228. }
  229.  
  230.  
  231. //----------------------------------------------------------------------
  232. static void    DrawValueCtl(VcPtr v)
  233. {
  234.     Str255        s;
  235.     Str255        st = "\ptrue";
  236.     Str255        sf = "\pfalse";
  237.     Rect        r;
  238.     long        w;
  239.     decimal        d;
  240.     decform        df;
  241.     
  242.     EraseRect(&v->wholeRect);
  243.     TextFont(geneva);
  244.     TextSize(9);
  245.     TextFace(0);
  246.     MoveTo(v->titlePos.h, v->titlePos.v);
  247.     DrawString(v->title);
  248.     if (v->mini == v->maxi) // separator
  249.         return;
  250.         
  251.     if (v->isCheckBox) {
  252.         if (v->currV == 1.0)
  253.             BlockMove(st, s, st[0]+1);
  254.         else
  255.             BlockMove(sf, s, sf[0]+1);
  256.     }
  257.     else {
  258.         df.style = FIXEDDECIMAL;
  259.         df.digits = 2;
  260.         num2dec(&df, v->currV, &d);
  261.         dec2str(&df, &d, (char *)s);
  262.         C2PStr((Ptr)s);
  263.     }
  264.     
  265.     TextFace(bold);
  266.     w = StringWidth(s);
  267.     MoveTo(v->valuePos.h - w, v->valuePos.v);
  268.     DrawString(s);
  269.  
  270.     r = v->incrHit;
  271.     FrameRect(&r);
  272.     if (v->isCheckBox) {
  273.         if (v->currV == 1.0) {
  274.             MoveTo(r.left, r.top);
  275.             LineTo(r.right - 1, r.bottom - 1);
  276.             MoveTo(r.left, r.bottom - 1);
  277.             LineTo(r.right - 1, r.top);
  278.         }
  279.     }
  280.     else {
  281.         MoveTo( r.left + 2, r.bottom - 2);
  282.         DrawChar('+');
  283.  
  284.         r = v->decrHit;
  285.         FrameRect(&r);
  286.         MoveTo(r.left + 2, r.bottom - 2);
  287.         DrawChar('-');
  288.     }
  289. }
  290.  
  291. //-----------------------------------
  292. static void    IncrementVC(VcPtr v)
  293. {
  294.     if (v->isCheckBox) {
  295.         if (v->currV == 0.0)
  296.             v->currV = 1.0;
  297.         else
  298.             v->currV = 0.0; 
  299.     }
  300.     else {
  301.         v->currV += v->delta;
  302.         if (v->currV > v->maxi)
  303.             v->currV = v->maxi;
  304.     }
  305. }
  306.  
  307.  
  308. //-----------------------------------
  309. static void    DecrementVC(VcPtr v)
  310. {
  311.     v->currV -= v->delta;
  312.     if (v->currV < v->mini)
  313.         v->currV = v->mini;
  314. }
  315.  
  316.  
  317. //----------------------------------------------------------------------
  318. //--------------------- ValueControlCluster routines -------------------
  319. //----------------------------------------------------------------------
  320. void    DrawVCluster(VccPtr    vcc)
  321. {
  322.     long     i;
  323.     Rect    r;
  324.     
  325.     FrameRect(&vcc->frame);
  326.     MoveTo(vcc->frame.left + 12, vcc->frame.top + 3);
  327.     TextFont(geneva);
  328.     TextSize(9);
  329.     TextFace(bold);
  330.     TextMode(srcCopy);
  331.     DrawChar(' '); DrawString(vcc->vTitle); DrawChar(' ');
  332.     r = vcc->resetHit;
  333.     EraseRect(&r);
  334.     FrameRect(&r);
  335.     MoveTo(r.left + 3, r.bottom - 2);
  336.     TextMode(srcOr);
  337.     DrawString("\pReset");
  338.     for (i = 0; i < vcc->howMany; i++)
  339.         DrawValueCtl(vcc->vCtls[i]);
  340. }
  341.  
  342. //----------------------------------------------------------------------
  343. void    DisposeVCluster(VccPtr    vcc)
  344. {
  345.     long i;
  346.     
  347.     for (i = 0; i < vcc->howMany; i++)
  348.         DisposePtr((Ptr)(&vcc->vCtls[i]));
  349.     DisposePtr((Ptr)vcc);
  350. }
  351.  
  352.  
  353. //----------------------------------------------------------------------
  354. OSType    GetIdTag(VccPtr    vcc)
  355. {
  356.     return vcc->idTag;
  357. }
  358.  
  359.  
  360. //----------------------------------------------------------------------
  361. float    GetCurrentValue(VccPtr vcc, long index)
  362. {
  363.     if ((index >= 0) && (index < vcc->howMany))
  364.         return     (vcc->vCtls[index])->currV;
  365.     else {
  366.         SysBeep(10);
  367.         return 0;
  368.     }
  369. }
  370.  
  371. //----------------------------------------------------------------------
  372. void    SetResetValue(VccPtr vcc, long index, float value)
  373. {
  374.     if ((index >= 0) && (index < vcc->howMany))
  375.         (vcc->vCtls[index])->initV = value;
  376.     else {
  377.         SysBeep(10);
  378.     }
  379. }
  380.  
  381.  
  382. //----------------------------------------------------------------------
  383. //---------------------   SettingsDialog routines   -------------------
  384. //----------------------------------------------------------------------
  385. static Boolean DoSettingsDialog(VcPtr v)
  386. {
  387.     DialogPtr        dlg;
  388.     GrafPtr            savePort;
  389.     ModalFilterUPP    filterProc;
  390.     OSErr            err;
  391.     short            item, kind;
  392.     Handle            h;
  393.     Rect            r;
  394.     
  395.     GetPort(&savePort);
  396.     dlg = GetNewDialog(kSettingsDlog, nil, (WindowPtr)(-1));
  397.     if (!dlg)
  398.         return false;
  399.     SetPort(dlg);    
  400.     err = GetStdFilterProc(&filterProc);
  401.     err = SetDialogDefaultItem(dlg, ok);
  402.     err = SetDialogCancelItem(dlg, cancel);
  403.     err = SetDialogTracksCursor(dlg, true);
  404.  
  405.     GetDialogItem(dlg, iVCtitle, &kind, &h, &r);
  406.     SetDialogItemText(h, v->title);
  407.     PutFloat(dlg, iMinValue, v->mini);
  408.     PutFloat(dlg, iMaxValue, v->maxi);
  409.     PutFloat(dlg, iStepSize, v->delta);
  410.     PutFloat(dlg, iCurrentV, v->currV);
  411.     
  412.     do {
  413.         ModalDialog(filterProc, &item);
  414.          switch (item) {
  415.          case ok: 
  416.          // range checks
  417.             break;
  418.         case iMinValue: 
  419.         // range check
  420.             break;
  421.         case iMaxValue:
  422.         // range check
  423.             break;
  424.         case iStepSize:
  425.         // range check
  426.             break;
  427.         case iCurrentV:
  428.         // range check
  429.             break;
  430.         }
  431.         if (item == ok) {
  432.             v->mini  = GetFloat(dlg, iMinValue);
  433.             v->maxi  = GetFloat(dlg, iMaxValue);
  434.             v->delta = GetFloat(dlg, iStepSize);
  435.             v->currV = GetFloat(dlg, iCurrentV);
  436.         }
  437.     } while ((item != cancel) && (item != ok));
  438.     
  439.     DisposeDialog(dlg);
  440.     SetPort(savePort);
  441.     return (item == ok);
  442. }
  443.  
  444.  
  445. //----------------------------------------------------------------------
  446. void    PutFloat(DialogPtr dlg, short item, float value)
  447. {
  448.     Str255        s;
  449.     Handle        h;
  450.     Rect        r;
  451.     decimal        d;
  452.     decform        df;
  453.     short        kind;
  454.     
  455.     df.style = FIXEDDECIMAL;
  456.     df.digits = 2;
  457.     num2dec(&df, value, &d);
  458.     dec2str(&df, &d, (char *)s);
  459.     C2PStr((Ptr)s);
  460.     GetDialogItem(dlg, item, &kind, &h, &r);
  461.     SetDialogItemText(h, s);
  462. }
  463.  
  464.  
  465. //----------------------------------------------------------------------
  466. float    GetFloat(DialogPtr dlg, short item)
  467. {
  468.     Str255        s;
  469.     Handle        h;
  470.     Rect        r;
  471.     decimal        d;
  472.     decform        df;
  473.     float        value = 0.0;
  474.     short        kind;
  475.     short        ix, vp;
  476.     
  477.     GetDialogItem(dlg, item, &kind, &h, &r);
  478.     if (h) {
  479.         GetDialogItemText(h, s);
  480.         P2CStr(s);
  481.         ix = 0;
  482.         str2dec((char *)s, &ix, &d, &vp);
  483.         if (vp) 
  484.             value = dec2f(&d);
  485.     }
  486.     return value;
  487. }
  488.  
  489.